package other.her.system.erp;

import com.alibaba.fastjson.JSONObject;
import com.rkhd.platform.sdk.ScheduleJob;
import com.rkhd.platform.sdk.api.annotations.RestApi;
import com.rkhd.platform.sdk.data.model.Product;
import com.rkhd.platform.sdk.exception.ScriptBusinessException;
import com.rkhd.platform.sdk.log.Logger;
import com.rkhd.platform.sdk.log.LoggerFactory;
import com.rkhd.platform.sdk.param.ScheduleJobParam;
import com.rkhd.platform.sdk.service.FutureTaskService;
import com.rkhd.platform.sdk.service.XoqlService;
import com.rkhd.platform.sdk.task.FutureTask;
import org.apache.commons.lang.StringUtils;
import other.her.system.client.ErpUtils;
import other.her.system.utils.HCXObjectService;
import other.her.system.utils.ResultVo;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description 同步ERP产品数据
 * @Author 黎炎松
 * 2024-10-09 17:47
 */
public class SyncProduct extends SyncSuper implements ScheduleJob, FutureTask {
    private static final Logger LOGGER = LoggerFactory.getLogger();
    private static final String LOGGER_MSG = "同步产品数据到CRM ==> ";

    /**
     * 计划作业触发
     * @param scheduleJobParam
     */
    @Override
    public void execute(ScheduleJobParam scheduleJobParam) {
        LOGGER.info(LOGGER_MSG + "触发计划作业");
        try {
            String messageId = FutureTaskService.instance().addFutureTask(getClass(), "2");
            LOGGER.info(LOGGER_MSG + "异步ID:" + messageId);
        } catch (Exception e) {
            LOGGER.error(LOGGER_MSG + " ----- 发生异常：" + e.getMessage());
        }
    }

    /**
     *
     * @param type
     * @throws ScriptBusinessException
     */
    @Override
    public void execute(String type) {
        LOGGER.info(LOGGER_MSG + "触发异步同步");
        // 执行同步
        startSyncData(Integer.parseInt(type));
    }


    public static void main(String[] args) {
        SyncProduct syncAccount = new SyncProduct();
        syncAccount.startSyncData(1);
    }


    /**
     * 开始同步不同账套ERP有变化的数据
     * @param type 1:首次批量处理 2：后续增量处理
     */
    public void startSyncData(int type) {
        for (Map<String, String> account : accountList) {
            if (type == 1) {
                initDataByAccount(account);
            } else {
                dealErpChangeDataByAccount(account);
            }
        }
    }

    /**
     * 增量处理ERP变化的数据
     */
    public void dealErpChangeDataByAccount(Map<String, String> account) {
        try {
            LOGGER.info(LOGGER_MSG + "开始处理新增、修改的产品数据: " + account.get("accountName"));

            // 查询ERP当前模块有变化的数据
            Map<String, String> module = moduleMap.get("cp");
            Map<String, String> idMap = getErpChangeData(module, account);
            if (idMap == null) {
                LOGGER.info("没有需要处理的数据");
                return;
            }

            // 新增、修改CRM数据
            String addUpIds = idMap.get("addUpIds");
            if (StringUtils.isNotBlank(addUpIds)) {
                String filterStr = String.format(" where t0.FitemID in (%s)", addUpIds);
                LOGGER.info(LOGGER_MSG + "filterStr: " + filterStr);
                ResultVo resultVo = syncErpAccount(account, filterStr);
                if (resultVo.getCode() != 200) {
                    return;
                }
            }


            // 删除CRM数据 (产品模块不需要删除)


            // 需要把ERP处理完的记录表数据删除
            delErpRecordTable(idMap.get("erpTableIds"), account);

        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.error(account.get("accountName") + ": 增量处理ERP变化的数据 => " + e.getMessage());
        }
    }

    /**
     * 首次初始化数据 （没有创建时间、修改时间，使用自动排序进行分页查询）
     * @param account
     */
    public void initDataByAccount(Map<String, String> account) {
        LOGGER.info(LOGGER_MSG + "开始初始化数据: " + account.get("accountName"));
        // 基础查询
        String baseSql = "select ROW_NUMBER() over(order by FitemID) as num,FitemID from t_IcitemCore ";

        // 获取当前模块的总数量
        String countSql = String.format("select count(*) as count from (%s) t", baseSql);
        JSONObject countObj = ErpUtils.queryOne(countSql, account.get("domain"));
        if (countObj == null) {
            LOGGER.error(LOGGER_MSG + "获取总数异常");
            return;
        }

        // 总数
        Integer tableCount = countObj.getInteger("count");
        LOGGER.info(LOGGER_MSG + "tableCount: " + tableCount);

        // 根据分页获取数据进行同步
        int startCount = 0;
        while (startCount < tableCount) {
            String filterSql = String.format(" where t0.FitemID in ( select FitemID from (%s) t where t.num between %d and %d )", baseSql, startCount, startCount += 100);
            LOGGER.info(LOGGER_MSG + "filterSql: " + filterSql);
             syncErpAccount(account, filterSql);
        }

    }


    /**
     * 同步erp客户数据
     * @return
     */
    public ResultVo syncErpAccount(Map<String, String> account, String filterStr) {
        try {
            LOGGER.info(LOGGER_MSG + "开始同步");
            int accountVal = Integer.parseInt(account.get("accountVal")); // CRM所属账套的值

            // 查询ERP产品数据
            String erpSql = "SELECT t0.FNumber,t0.FName,t4.FFullName,t0.FModel,t0.FHelpCode,t0.FDeleted,t1.FVersion,t4.FSaleUnitID,t2.FQtyMax,t2.FQtyMin," +
                    "  t0.FItemID,t0.FOrderPrice,t3.FProfitRate,t4.FErpClsID,t4.FUseState,t5.F_102,t5.F_104,sub.FName as className,unit.FName as unitName " +
                    "  from t_ICItemCore t0 \n" +
                    "  left join t_ICItemDesign t1 on t0.FItemID = t1.FItemID\n" +
                    "  left join t_ICItemPlan t2 on t0.FItemID = t2.FItemID\n" +
                    "  left join t_ICItemMaterial t3 on t0.FItemID = t3.FItemID\n" +
                    "  left join t_ICItemBase t4 on t0.FItemID = t4.FItemID\n" +
                    "  left join t_ICItemCustom t5 on t0.FItemID = t5.FItemID \n" +
                    "  left join t_SubMessage sub on t4.FErpClsID = sub.FinterID \n" +
                    "  left join t_MeasureUnit unit on t4.FSaleUnitID = unit.FMeasureUnitID ";

            // 增加过滤条件
            if (StringUtils.isNotBlank(filterStr)) {
                erpSql += filterStr;
            }

            List<JSONObject> productList = ErpUtils.query(erpSql, account.get("domain"));
            LOGGER.info(LOGGER_MSG + "productList: " + productList.size());
            if (productList == null && productList.size() <= 0) {
                LOGGER.info(LOGGER_MSG + "查询异常或者没有需要同步的产品数据");
                return ResultVo.success();
            }

            // 查询CRM系统是否已经存在
            String fNumbers = productList.stream().map(v -> "'" + v.getString("FNumber") + "'").collect(Collectors.joining(","));
            String sql = String.format("select id,productName from product where zhangtao__c = %d and productName in (%s)", accountVal, fNumbers);
            Map<String, Long> crmProductMap = XoqlService.instance().query(sql).getRecords().stream().collect(Collectors.toMap(e -> e.getString("productName"), e1 -> e1.getLong("id")));
            LOGGER.info(LOGGER_MSG + "crmProductMap: " + crmProductMap);

            // 新增、修改产品数据
            List<Product> addProductList = new ArrayList<>();
            List<Product> upProductList = new ArrayList<>();
            for (JSONObject erpProduct : productList) {
                Product product = new Product();

                String fNumber = erpProduct.getString("FNumber");
                product.setProductName(fNumber); // 产品编码
                product.setERPID__c(erpProduct.getString("FItemID")); // ERPID
                product.setProductMc__c(erpProduct.getString("FName")); // 产品名称
                product.setFscProductSpec(erpProduct.getString("FModel")); // 规格型号
                product.setUnit(erpProduct.getString("unitName")); // 销售单位
                product.setFHelperCode__c(erpProduct.getString("FHelpCode")); // 助记码
                product.setFVersion__c(erpProduct.getString("FVersion")); // 版本号
                product.setFQtyMax__c(erpProduct.getDouble("FQtyMax")); // 最大订货量
                product.setFQtyMin__c(erpProduct.getDouble("FQtyMin")); // 最小订货量
                product.setFOrderPrice__c(erpProduct.getDouble("FOrderPrice")); // 订货单价
                product.setFProfitRate__c(erpProduct.getDouble("FProfitRate")); // 毛利率
                product.setFullName__c(erpProduct.getString("FFullName")); // 全名
                product.setFClass__c(erpProduct.getString("className")); // 物料属性
                product.setLicenseCode__c(erpProduct.getString("F_104")); // 生产许可证编号
                product.setVoucher__c(erpProduct.getString("F_102")); // 注册证号或备案凭证编号

                // 启用状态 1:启用  2:禁用
                Integer fDeleted = erpProduct.getInteger("FDeleted");
                product.setEnableStatus(fDeleted == 1 ? 2 : 1);

                //product.setManufacturer__c(erpProduct.getString("F_105")); // 生产厂家
                //product.setBrand__c(erpProduct.getString("F_103")); // 品牌


                if (crmProductMap.containsKey(fNumber)) {
                    // 编辑
                    product.setId(crmProductMap.get(fNumber));
                    upProductList.add(product);
                } else {
                    // 新增
                    product.setEntityType(11010000400001l); // 业务类型
                    product.setParentId(3448470071302833L); // 所属目录
                    product.setZhangtao__c(accountVal); // 所属账套
                    addProductList.add(product);
                }

                // 批量新增、更新
                if (addProductList.size() > 50) {
                    HCXObjectService.insertBatch(addProductList);
                    addProductList.clear();
                }
                if (upProductList.size() > 50) {
                    HCXObjectService.updateBatch(upProductList);
                    upProductList.clear();
                }
            }

            // 批量保存产品数据
            HCXObjectService.insertBatch(addProductList);
            HCXObjectService.updateBatch(upProductList);

            LOGGER.info(LOGGER_MSG + "同步结束");
            return ResultVo.success();
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.error("同步产品异常:" + e.getMessage());
            return ResultVo.error("同步产品异常:" + e.getMessage());
        }
    }


}
